package edu.uc.labs.MobilePrinting;

import edu.uc.labs.MobilePrinting.Fetch.XMLFetcher;
import edu.uc.labs.MobilePrinting.OSUtils.IPAddressFinder;
import edu.uc.labs.MobilePrinting.GUI.SysTray;
import edu.uc.labs.MobilePrinting.PrintUtils.*;
import java.io.*;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import org.apache.log4j.Logger;



/**
 *
 * @author Matt Silbernagel
 */
public class MobilePrintRunner {
    
    private static XMLFetcher s = null;
    private static ArrayList<Printer> prnts = null;
    private static boolean needsToRun = true;
    private static IPAddressFinder ip = null;
    private static String oldIP = null;
    private static String newIP = null;
    
    private static Logger logger = Configurator.LOGGER;
    private static String cache_dir = Configurator.CACHEDIR;
    private static String os = Configurator.OS;
    

    ////////////////////////////////////////////
    // CONSTANTS
    ////////////////////////////////////////////

    // SLEEP
    final static int SLEEP = 10000;
    final static int SLEEP_LONG = 30000;
  

    // PRINTER, ETC
    final public static String PORTNAME = "UCitMobilePrinter";
    final public static String PRINTERNAME = "UCitMobilePrinter";
    
    
    /**
     * The class that implements the main service
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {       
        // Make sure all directories and
        // files that we need are in place
        Installer i = new Installer();
        i.install();
              
        // Start the program in the SysTray
        SysTray prn = new SysTray();
        prn.add(PrinterFinder.getList(cache_dir));

        //Get Current IP Address
        logger.debug("Getting ip address...");
        
        try {
            ip = new IPAddressFinder();
            oldIP = ip.getIP();
        } catch (UnknownHostException e){            
            logger.error("Instantiating class IPAddressFinder " + e.toString());            
        }
        // Get a connection to the HTTP_SERVER
        checkConnection(oldIP);

        // This is our main Loop/Service
        while (true) {
            logger.debug("In the main loop... ");
            logger.debug("Current IP = " + oldIP);

            // See if our IP Address has changed
            try {
                logger.debug("Getting a new IP ");
                IPAddressFinder getNewIP = new IPAddressFinder();                
                newIP = getNewIP.getIP();
                logger.debug("New IP = " + newIP + ", old IP = " + ip.getIP() + " or " + oldIP);
            } catch (UnknownHostException e){
                logger.debug("Caught an UnknownHostException, setting the new IP to 127.0.0.1");
                newIP = "127.0.0.1";
            }
            
			if ((!newIP.equals(oldIP)) || needsToRun  ) {
                // needsToRun ensures that this if
                // statement runs at least once during
                // first run
                needsToRun = false;
                oldIP = newIP;
                logger.debug("The IP has changed, the new value is " + oldIP);
                // Make sure we can still connect with our new IP
                if(!checkConnection(newIP)) {
                    logger.debug("Writing a blank xml file");
                    PrinterParser.buildXMLFile(new File(cache_dir + Configurator.DELIM + Configurator.XMLFILE));                    
                }else {
                    // We have a new Configuration, Lets write it to a cache directory
                    logger.debug("Writing a new config file");
                    writeConfiguration();
                }
                // Do the work we need to do if IP has changed
                prnts = PrinterFinder.getList(cache_dir);
                // Should we delete the printer if prnts is empty???
                prn.add(prnts);
            } else {
                logger.debug("You IP hasn't changed, trying to sleep... ");
            }
            try {
                Thread.sleep(SLEEP);
            } catch (InterruptedException ex) {
                logger.debug(ex.toString());
            }
        }
    }

    public static boolean checkConnection( String ipaddress ) throws IOException {
        while (true) {            
            try {
                s = new XMLFetcher(Configurator.HTTP_SERVER, ipaddress, os);
                // Good we can connect to the server
                // now break out of this loop                
                return true;
            } catch (UnknownHostException e) {                
                // Are we on the UC Network?
                // Set the printer to Paused?
                JOptionPane.showMessageDialog(null, "Please connect to the VPN");
                return false;
            } catch (ConnectException e) {
                // Are we on the UC Network?
                // Set the printer to Paused?
                JOptionPane.showMessageDialog(null, "Please connect to the VPN");
                return false;
            } catch (NullPointerException e) {
                logger.debug("Caught a NullPointerException in the checkConnection method");
            }
           
        }
    }

    /**
     * 
     * @throws FileNotFoundException
     */
    public static void writeConfiguration() throws FileNotFoundException {
        try {
            String file_name = cache_dir + Configurator.XMLFILE;            
            FileWriter fstream = new FileWriter(file_name);
            BufferedWriter out = new BufferedWriter(fstream);
            out.write(s.getResponse());
            out.close();
        } catch (IOException ex) {
            logger.error(ex.getMessage());
        }
    }
}
